﻿using System;
using UnityEngine;

public class HorizontalGridScrollListCreator : GridScrollListCreator
{
    protected override int ConstraintCount { get { return cellCountY; } }

    public override void Init(ScrollRectEx tool, IScrollList scrollList)
    {
        base.Init(tool, scrollList);
    }

    public override void SetNormalizePosition(float normalize)
    {
        var offset = tool.content.rect.width - tool.viewRect.rect.width;
        var pos = tool.content.anchoredPosition;
        pos.x = -offset * normalize;

        tool.SetContentAnchoredPositionSimple(pos);
    }

    public override bool IsMoveNextDirection(Vector2 delta)
    {
        return delta.x < 0;
    }

    public override bool IsMoveBeforeDirection(Vector2 delta)
    {
        return delta.x > 0;
    }

    public override bool IsCanRecycleBegin()
    {
        if (activeList.Count == 0)
            return false;

        var min = tool.contentBounds.min.x + layout.padding.left + layout.cellSize.x + layout.spacing.x;
        if (min < tool.viewBounds.min.x)
            return true;

        return false;
    }

    public override bool IsCanRecycleEnd()
    {
        if (activeList.Count == 0)
            return false;

        var max = tool.contentBounds.max.x - layout.padding.right - layout.cellSize.x - layout.spacing.x;
        if (max > tool.viewBounds.max.x)
            return true;

        return false;
    }

    public override bool IsNeedCreateNext()
    {
        var offset = tool.viewBounds.max.x - tool.contentBounds.max.x + layout.padding.right;
        if (offset > 0 || Mathf.Abs(offset) < offsetRange)
            return true;

        var lastLineCount = activeList.Count % ConstraintCount;
        if (lastLineCount != 0)
            return true;

        return false;
    }

    public override bool IsNeedCreateBefore()
    {
        var offset = tool.viewBounds.min.x - tool.contentBounds.min.x - layout.padding.left;
        if (offset < 0 || Mathf.Abs(offset) < offsetRange)
            return true;

        return false;
    }

    protected override void RecycleBegin()
    {
        for (int i = 0; i < ConstraintCount && i < activeList.Count; i++)
            RecycleItem(i, activeList[i]);

        MoveNextLine();
    }

    protected override void RecycleEnd()
    {
        UpdateActiveList();

        var lineCount = activeList.Count % ConstraintCount;
        var endLineCount = lineCount == 0 ? ConstraintCount : lineCount;
        for (int i = 0; i < endLineCount && i < activeList.Count; i++)
        {
            var itemIndex = activeList.Count - 1 - i;
            RecycleItem(itemIndex, activeList[itemIndex]);
        }

        m_lastItemChange(-endLineCount);
    }

    protected override RectTransform NewNext(int createIndex)
    {
        if (IsCanRecycleBegin())
            RecycleBegin();

        var item = PopItem();
        item.SetAsLastSibling();
        m_lastItemChange(1);
        return item;
    }

    protected override RectTransform NewBefore(int createIndex)
    {
        var item = PopItem();
        item.SetAsFirstSibling();

        if (createIndex == (ConstraintCount - 1))
        {
            MoveBeforeLine();
            tool.UpdateContent();
            if (IsCanRecycleEnd())
                RecycleEnd();
        }

        return item;
    }

    private void MoveBeforeLine()
    {
        var offset = layout.cellSize.x + layout.spacing.x;
        var pos = tool.content.anchoredPosition;
        pos.x -= offset;

        tool.SetContentAnchoredPositionSimple(pos);
    }

    private void MoveNextLine()
    {
        var offset = layout.cellSize.x + layout.spacing.x;
        var pos = tool.content.anchoredPosition;
        pos.x += offset;
        tool.SetContentAnchoredPositionSimple(pos);
    }
}